

import time

#SOURCE ilabel.c by lute.ai moving the mathlab codes to pure C codes.
'''/*LABEL ilabel.c
 *
 * Fast image labelling funciton.
 *
 *  L = ILABEL(IM [,OPT])
 *  [L,LMAX] = ILABEL(IM)
 *  [L,LMAX,PARENTS] = ILABEL(IM)
 *  [L,LMAX,PARENTS,COLOR] = ILABEL(IM)
 *  [L,LMAX,PARENTS,COLOR,EDGE] = ILABEL(IM)
 *
 * Copyright (C) 1995-2009, by Peter I. Corke
 *
 * This file is part of The Machine Vision Toolbox for Matlab (MVTB).
 * 
 * MVTB is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * MVTB is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Leser General Public License
 * along with MVTB.  If not, see <http://www.gnu.org/licenses/>.
 *
 */'''
import numpy as np
import os
import math
_lmap = np.zeros(104424, dtype=np.int)
def ilabel(_img, width, height, connectivity, minsize, _limg, __parent_out, __color_out, __edge_out):
	row = col = i = j = nlabels = 0
	prevlab = curlab = 0
	_parents = np.zeros(104424, dtype=np.int)
	curpix = prevpix = 0
	maxlabel = width*height
	#_color = None
	#_edge = None
	_color = np.zeros(maxlabel, dtype=np.int)
	_edge = np.zeros(maxlabel, dtype=np.int)

	#allocate label map and init to zero
	global _lmap #= np.zeros((maxlabel), dtype=np.int)
	#region size
	_blobsize = np.zeros((maxlabel), dtype=np.int)
	
	if(__parent_out):
		_parents = np.zeros((maxlabel), dtype=np.int)
	if(__color_out):
		_color = np.zeros((maxlabel), dtype=np.int)
	if(__edge_out):
		_edge = np.zeros((maxlabel), dtype=np.int)
	

	"""core maths"""
	for row in range(0,height):
		for col in range(0,width):
			curpix = _img[row + height*col]
			#print(curpix)
		#print("\n")
	#first pass labelling loop. Only does 4-way connnectivity
	newlabel = 0
	for row in range(0,height):
		prevlab = 0
		for col in range(0,width):
			curpix = _img[row + height*col]
			curlab = 0 #start with unknown label
			if(col > 0):
				prepix = _img[row + height*(col-1)]
				#if no change in pixel value then inherit label from left
				if(curpix == prevpix):
					curlab = prevlab
			#print("(%d,%d) cp=%d, pp=%d, cl=%d, pl=%d\n"%( row, col, curpix, prevpix, curlab, prevlab))
			"""check whether a label merge should happen, adjacent pixels with the same value but different labels means that one should change. merge can only happen on second row onwards"""
			if(row > 0):
				if((_img[(row-1) + height*col] == curpix) and (lresolve(_limg[(row-1) + height*col]) != curlab)):
					#label assign from N
					newlabel = lresolve(_limg[(row-1) + height*col])
					#print("mergeN(%d,%d): %d becomes %d: curpix=%d, prevpix=%d\n"%( row, col, curlab, newlabel, curpix, _img[(row-1)*height+col]))
					#newlabel dominates
					if(curlab != 0):
						_lmap[curlab] = newlabel
						_blobsize[newlabel] += _blobsize[curlab]
						if(_parents[curlab] == 0):
							_parents[newlabel] = 0
					curlab = newlabel
				elif(connectivity == 8 and (col > 0) and (_img[(row-1) + height*(col-1)]== curpix) and (lresolve(_limg[(row-1) + height*(col-1)]) != curlab)):
					#merge to NW
					newlabel = lresolve(_limg[(row-1) + height*(col-1)])
					#print("mergeNW(%d,%d): %d becomes %d\n"%( row, col, curlab, newlabel))
					if(curlab != 0):
						_lmap[curlab] = newlabel
					if(_parents[curlab] == 0):
						_parents[curlab] = 0
					_blobsize[newlabel] += _blobsize[curlab]
					curlab = newlabel
				elif(connectivity == 8 and (col<(width-1)) and (_img[(row-1) + height*(col+1)] == curpix) and (lresolve(_limg[(row-1) + height*(col+1)]) != curlab)):
					#merge to NE
					newlabel = lresolve(_limg[(row-1) + height*(col+1)])
					#print("mergeNE(%d,%d): %d becomes %d\n"%( row, col, curlab, newlabel))
					if(curlab != 0):
						_lmap[curlab] = newlabel
					_blobsize[newlabel] += _blobsize[curlab]
					curlab = newlabel
			if((row > 0) and (col > 0)):
				#check for enclosure
				left = above = northwest = 0
				left = prevlab
				above = lresolve(_limg[(row-1) + height*col])
				northwest = lresolve(_limg[(row-1) + height*(col-1)])
				if(left == curlab and above == curlab and northwest != curlab):
					#print("(%d,%d): label %d encloses %d\n"%(row, col, curlab, northwest ))
					#we have an enclosure
					if(_blobsize[curlab] > 0):
						_parents[northwest] = curlab
					else:
						_lmap[curlab] = northwest
			"""if label still not known, assign new"""
			if(curlab == 0):
				newlabel = newlabel + 1
				curlab = newlabel
				_color[curlab] = curpix
				_edge[curlab] = row + height*col + 1
				#print("new label(%d,%d): %d\n"%(row, col, curlab))
			_blobsize[curlab] += 1
			_limg[row + height*col] = curlab
			prevlab = curlab
			prevpix = curpix
	#print("max lim is %d\n" % newlabel)
	
	"""indirection| create a new label map that maps all old labels to new consecutive labels"""
	_lmap2 = np.zeros(maxlabel, dtype=np.int)
	#create a vector of all the final label values, ie. _lmap[i] == 0
	#print("-------------------\nlmap:\n")
	nlabels = 0
	for i in range(1, newlabel+1):
		#print("(%d) = %d\n" % (i, _lmap[i]))
		if(_lmap[i] == 0):
			nlabels = nlabels + 1
			_lmap2[i] = nlabels #assign new sequential label
	#now resolve each labels appear in the labelled image
	for i in range(0, newlabel+1):
		if(_lmap[i] != 0):
			j = lresolve(i)
			_lmap2[i] = _lmap2[j]
	#one debug block
	#another debug block
	"""resolve the labels in the parent array and assign to double proc output array"""
	if(__parent_out):
		lab = np.zeros(nlabels, dtype=np.int)
		for i in range(1, newlabel+1):
			par = _parents[i]
			child = 0
			if(par):
				child = _lmap2[i]
				par = _lmap2[par]
				lab[child-1] = par
		parents = None
		__parent_out = lab
	if(__color_out or __edge_out):
		c = np.zeros(nlabels, dtype=np.int)
		e = np.zeros(nlabels, dtype=np.int)
		for i in range(1,newlabel+1):
			l = _lmap2[i]
			c[l-1] = _color[i]
			if(e[l-1] == 0):
				e[l-1] = _edge[i]
		if(__color_out):
			color = None
			__color_out = c
		if(__edge_out):
			edge = None
			__edge_out = e
	"""resolve the labels in the integer labelled image and assign to the double prec. output image""" 
	for row in range(0, height):
		for col in range(0, width):
			_limg[row + height*col] = _lmap2[_limg[row + height*col]]
	_lmap = None
	_lmap2 = None
	_blobsize = None
	return nlabels			

"""resolve a label to its true value via the label map"""
def lresolve(l):
	#global _lmap
	i = l
	while(_lmap[i] > 0):
		i = _lmap[i]
	#debug block
	return i



def main():
	time_start = time.time()
	#read test data, hard code the number of elements
	im_height = 228
	im_width = 458
	nlabels = im_height * im_width
	_im = np.zeros((nlabels), dtype=np.int)
	_out_im = np.zeros((nlabels), dtype=np.int)
	_parent_out = None
	_color_out = None
	_edge_out = None
	_im = np.loadtxt("diffDataSign.txt", dtype=np.int)
	#max_label = ilabel(_im, im_height, im_width, 4, 0, _out_im, _parent_out, _color_out, _edge_out)
	#_parent_out = None
	#_color_out = None
	#_edge_out = None
	#time_end = time.time()
	#print time_end - time_start,
	#print 's'
	
	max_label = ilabel(_im, im_height, im_width, 8, 0, _out_im, _parent_out, _color_out, _edge_out)
	_parent_out = None
	_color_out = None
	_edge_out = None
	time_end= time.time()
	print time_end - time_start
	print 's'


if __name__ == "__main__":
	main()

